<template>
    <div class=" bg_img">
        <div class="layout">

            <div class="chat-panel-header" v-if="props.dialogues && props.dialogues.length > 0 && route.path == '/knowledge'">
                <span class="chat-title"></span>
                <el-link class="clear-chat-btn" @click="handleClearChat" title="清空对话">
                    <el-icon>
                        <Delete />
                    </el-icon>
                </el-link>
            </div>
            <div class="content_wrapper">
                <!-- :style="{ padding: contentPadding }" -->
                <div class="content_layoutfa">
                    <div class="content_layout">
                        <!-- 空状态提示 -->
                        <div v-if="route.path == '/knowledge' &&  messageBackupList.length === 0" class="empty-chat-state">
                            <div class="empty-chat-content">
                                <img src="../../assets/chat-icon.svg" alt="聊天图标" class="chat-icon">
                                <div class="empty-chat-text">有任何关于这个知识库的问题，都尽管问</div>
                            </div>
                        </div>

                        <!-- 聊天记录 -->
                        <div class="chat_content" ref="chatLayout" v-for=" (item, index) in messageBackupList" :key="index">
                            <!-- 右侧布局 -->
                            <div v-if="item.role == 'user'" style="position: relative;">
                                <div class="right_layout">
                                    <div class="chat_layout ">
                                        <div class="text_align_r">
                                            <!-- <div class="quiz" v-html="md.render(item.content)"></div> -->
                                            <div class="quiz" v-html="item.content"></div>

                                        </div>
                                        <img class="assets_img margin_l10" src="../../assets/accent.png" alt="默认头像">
                                    </div>
                                </div>
                            </div>
                            <!-- 左侧布局 -->
                            <div v-if="item.role == 'assistant'" style="position: relative;">
                                <div class="left_layout">
                                    <div class="chat_layout">
                                        <img class=" assets_img " src="../../assets/assets.png" alt="默认头像">
                                        <div>
                                            <div v-if="item.loading == true" class="answer margin_l10" style="display: flex; align-items: center;">
                                                <img class="loading_img" src="../../assets/loading.gif" alt="正在思考中...">
                                                <span style="margin-left: 10px;color: black;">正在思考中... </span>
                                            </div>

                                            <div v-else class="answer margin_l10">
                                                <div class="file-list-container" style="padding-left: 0;" v-if="item.files_appendix?.length > 0">
                                                    <div @click="handleFileClick(item)" v-for="item in item.files_appendix" :key="item._id" class="file-item" style="cursor: pointer;width: 200px; height: 50px;padding: 10px;">
                                                        <!-- 文件类型图标 -->
                                                        <img :src="getFileTypeImage(item.file_type)" alt="" class="file-icon" />
                                                        <div class="file-info" style="gap:0">
                                                            <div class="file-name" :title="item.file_name">{{ item.file_name }}</div>
                                                            <div class="file-meta">
                                                                <div>{{ item.file_type }}</div>
                                                                <div>{{ item.file_size }}</div>
                                                            </div>
                                                        </div>
                                                    </div>
                                                </div>
                                                <!-- 没找到相关内容时的提示 -->
                                                <div class="no-result" v-if="item.foundresult?.length == 0 || item.foundresult == null && item.depend_lib">
                                                    <p class="no-result-tip">没有找到相关的知识库内容</p>
                                                </div>
                                                <div v-else>
                                                    <!-- 相关知识库资料 -->
                                                    <div class="related-docs" v-if="item.foundresult?.length > 0">
                                                        <div class="related-docs-header" @click="toggleDocsExpand(item)">
                                                            <span>找到 {{ item.foundresult.length }} 篇相关知识库资料作为参考</span>
                                                            <el-icon :class="{ 'is-expand': item.isunpack }">
                                                                <ArrowDown />
                                                            </el-icon>
                                                        </div>

                                                        <!-- 相关文档列表 -->
                                                        <div v-show="item.isunpack" class="related-docs-list">
                                                            <div v-for="(doc, index) in item.foundresult" :key="doc.id" class="doc-item" @click="handleDocClick(doc)">
                                                                <span class="doc-index">{{ index + 1 }}</span>
                                                                <span class="doc-name" :title="doc.file_name">{{ doc.file_name }}</span>
                                                                <!-- <span class="doc-type">{{ doc.file_type }}</span> -->
                                                            </div>
                                                        </div>
                                                    </div>
                                                </div>

                                                <!-- 占位 -->
                                                <div :class="'Occupyposition_' + index" v-if="item.mindmap">
                                                </div>

                                                <div v-if="item.foundloading == true" class="answer margin_l10" style="display: flex; align-items: center;margin-left: 0;padding-left: 0;">
                                                    <img class="loading_img" src="../../assets/loading.gif" alt="正在思考中...">
                                                    <span style="margin-left: 10px;color: black;">正在搜索中... </span>
                                                </div>

                                                <!-- AI 回答内容 -->
                                                <div class="ai-answer" v-else>
                                                    <div v-html="item.content"></div>
                                                    <div v-if="item.netlisk && item.netlisk.length > 0">
                                                        <el-button v-for="(card,index) in item.netlisk" :key="index" type="text" @click="openLink(card.url)">{{ card.title }}</el-button>
                                                    </div>
                                                </div>
                                                <!-- 操作提示 -->
                                                <div v-if="showDisabled == false" class="operation-tip">
                                                    <!-- {{ tip }} -->
                                                </div>
                                            </div>

                                        </div>
                                    </div>

                                </div>
                            </div>
                        </div>
                        <!-- <div style="height: 600px;"></div> -->
                        <!-- 输入框和文件上传框 -->
                        <!-- 文件上传 -->
                        <div class="file_content" v-if="show_upload">
                            <div class="content_file" style="">
                                <div class="file_txt">上传文件</div>
                                <img class="file_close" src="../../assets/close.png" alt="" @click="closeHeadler">
                            </div>
                            <div class="upload_file">
                                <el-upload class="upload-demo upload" drag multiple action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15">
                                    <div class="upload_text">
                                        <a>点击上传</a>
                                        <span>或拖入文档</span>
                                    </div>
                                    <div class="remark">最多10个文件，单个文件最大50MB，支持Word/PDF/TXT/Excel/PPT</div>
                                </el-upload>
                            </div>

                        </div>
                        <!-- 输入框 -->
                        <div class="search_layout">
                            <!-- 数字人 -->

                            <div class="hot-question-list" :style="{ display: isShow ? 'block' : 'none' }" v-if="questionList?.length > 0">
                                <div v-for="(item, index) in questionList" :key="index" @click="sendTipQuestion(item)">
                                    <div class="hot-question-item" style=" cursor: pointer;">
                                        <span style="margin: 0 5px 0 0;">
                                            {{ index + 1 }} .
                                        </span>
                                        <span class="hot-question-item-title">
                                            {{ item }}
                                        </span>
                                    </div>
                                </div>
                            </div>
                            <SpeechInput ref="stopimport" @speech-result="handleSpeechResult" />
                            <div style="display: flex;align-items: center;margin: 0 0 8px 0;position: relative;">

                                <div class="Digitalhuman" v-show="scaleFactor > 0.65" :style="{ transform: `scale(${scaleFactor})`}" :class="{ 'hidden': !isDigitalHumanVisible, 'visible': isDigitalHumanVisible }">
                                    <img style="    transform-origin: top center;border-radius: 5% 5% 0 0;
" src="@/assets/Digitalhuman7.png" v-show="!isSpeaking" alt="">
                                    <img style="    transform-origin: top center;border-radius: 5% 5% 0 0;
" src="@/assets/Digitalhuman7plus.gif" v-show="isSpeaking" alt="">
                                    <!-- <canvas id="mouthCanvas" width="320px" height="370px" :style="{  position: 'absolute', left: '0', top: '0',    transformOrigin:' top center'
 }"></canvas> -->
                                    <div class="Readingswitch" v-if="scaleFactor > 0.65">
                                        <el-tooltip class="item" effect="dark" content="开启朗读" placement="top" v-if="!isReadingEnabled">
                                            <img class="btnimg" style="width: 23px;height: 23px;" @click="toggleReading" src="@/assets/Reading0.png" alt="">
                                        </el-tooltip>
                                        <el-tooltip class="item" effect="dark" content="关闭朗读" placement="top" v-else>
                                            <img class="btnimg" @click="toggleReading" src="@/assets/Reading1.png" alt="">
                                        </el-tooltip>
                                        <el-tooltip class="item" effect="dark" content="收起数字人" placement="top">
                                            <img class="btnimg" @click="hideDigitalHuman" src="@/assets/shouqi.png" alt="">
                                        </el-tooltip>
                                    </div>
                                </div>
                                <el-tooltip class="item" effect="dark" content="展开数字人" placement="top">
                                    <img class="xzs" src="@/assets/xzs.png" @click="startxzs" alt="">
                                </el-tooltip>
                                <button class="CollapseExpand" @click="hot_questionisshow">收起/展开 </button>
                            </div>
                            <div v-if="showDisabled" class="stop-tip">
                                <el-button class="stop-btn" type="danger" size="small" @click="stopGeneration">
                                    <el-icon>
                                        <CircleClose />
                                    </el-icon>
                                    停止回答
                                </el-button>
                            </div>
                            <div class="file-list-container" style="max-height: 267px;overflow: auto;" v-if="isIndeterminate?.length > 0">
                                <div v-for="(item,index ) in isIndeterminate" :key="item._id" class="file-item">
                                    <!-- 删除图标 -->
                                    <button @click="deleteFile(index)" class="delete-icon">
                                        &times; <!-- X 图标 -->
                                    </button>
                                    <!-- 文件类型图标 -->
                                    <!-- <img :src="getFileTypeImage(item.file_type)" alt="" class="file-icon" /> -->
                                    <img style="width: 30px;height: 30px;border-radius: 10px;" :src="item.img_url" alt="" class="file-icon" />

                                    <div class="file-info">
                                        <div class="file-name" :title="item.file_name">{{ item.file_name }}</div>
                                        <div class="file-meta">
                                            <div>{{ item.file_type }}</div>
                                            <div>{{ item.file_size }}</div>
                                        </div>
                                    </div>
                                </div>
                                <div class="card_bth">
                                    <div class="div" @click="summarycontent">总结内容</div>
                                    <div class="div" @click="generatemindmap">生成思维导图</div>
                                </div>
                            </div>
                            <!-- 根据知识库id询问 :disabled="props.currentKnowledge?._id ? false : true" -->
                            <el-input :disabled="props.currentKnowledge || props.currentHistory ? false : true" v-model="search" class="input_layout" type="textarea" :autosize="{ minRows: 1.4, maxRows: 7 }" placeholder="请咨询您的任何问题  Ctrl + Enter换行" @input="searchChange" @keydown="handleKeydown">
                            </el-input>

                            <div class="search" v-if="(props.currentKnowledge  || props.currentHistory) && !showDisabled">

                                <img v-if="!showDisabled" class="search_img" src="../../assets/search.png" alt="发送" @click="sendHeadler">
                            </div>

                            <div class="bottom_arrow" v-if="showDisabled && loadingscroll" @click="scrollToBottomchange"><el-icon size="20">
                                    <Bottom />
                                </el-icon>
                            </div>

                        </div>
                        <div class="operation-tip">
                            {{ tip }}
                        </div>
                        <!-- // 在列表底部放置哨兵元素 -->
                        <div ref="sentinel" style="height: 20px;"></div>

                    </div>
                </div>

            </div>

        </div>
        <!-- 导入内容 -->
        <el-dialog v-model="Toleadintoopen" title="导入内容">
            <el-table @row-click="handleRowClick" header-cell-class-name="hide-header-checkbox" ref="scrollTable" height="400" :data="istemporarily" @selection-change="handleSelectionChange" :row-key="row => row._id">
                <el-table-column type="selection" width="55" />
                <el-table-column prop="file_name" label="个人知识库" min-width="180">
                    <template #default="scope">
                        <div style="display: flex; align-items: center;">
                            <img style="width: 30px; height: 30px; margin-right: 8px;border-radius: 20px;" :src="scope.row.img_url" alt="">
                            <span>{{ scope.row.file_name }}</span>
                        </div>
                    </template>
                </el-table-column>
            </el-table>

            <template #footer>
                <span class="dialog-footer">
                    <el-button type="primary" @click="confirmBatch" :disabled="ids.size > 0 ? false : true">确认</el-button>
                </span>
            </template>
        </el-dialog>

    </div>
</template>

<script>
import MarkdownIt from 'markdown-it'
import { useRouter, useRoute } from 'vue-router'
import { getCurrentInstance } from 'vue'
import { ElMessage } from 'element-plus'
import { clear_msg, agree_msg, disagree_msg, stop_dialogue } from "@/api/chatmessage"
import { agree_msghis, disagree_msghis } from "@/api/historycross"
import { getToken, setToken, removeToken } from '@/utils/auth'


import hljs from 'highlight.js'
import 'highlight.js/styles/github.css'

export default {
    name: 'DialogueView'
}
</script>

<script setup>
// 导入 Clipboard.js
import ClipboardJS from 'clipboard';
import {
    ref,
    onMounted,
    onUnmounted,
    nextTick,
    watch,
    defineProps,
    defineEmits,
    defineExpose,
    computed,
    reactive,
    onBeforeUnmount
} from 'vue'
import {
    Plus, Folder, Document, Edit, Delete, Upload,
    User, Share, DocumentCopy, ArrowDown, FolderOpened,
    FolderAdd, Calendar, UploadFilled, Close, CircleClose,
    Microphone, MicrophoneSlash
} from '@element-plus/icons-vue'
// import { Close, CircleClose, ArrowDown, CaretBottom } from '@element-plus/icons-vue'
import { useRouter, useRoute } from 'vue-router'
import { getCurrentInstance } from 'vue'
import { ElMessage, ElButton } from 'element-plus'
import { clear_msg, agree_msg, disagree_msg, stop_dialogue, modelOptionslist, user_files } from "@/api/chatmessage"
import { agree_msghis, disagree_msghis } from "@/api/historycross"
import { getToken, setToken, removeToken } from '@/utils/auth'
import hljs from 'highlight.js'
import 'highlight.js/styles/github.css'
import { sseRequset } from '@/utils/sserequest'
import modelStore from "@/store/modules/model.js";
import "jsmind/style/jsmind.css";
import JsMind from "jsmind";
import html2canvas from 'html2canvas';


import { getQuestion, getAnswer } from "@/api/index.js"
import mouthImage from '@/assets/Digitalhuman4ss.png'  // 添加图片导入

// 防抖初始值
let debounceTimer = null;
// 联想词汇
let questionList = ref([])
let isShow = ref(true)


const modelStorestate = modelStore();
const moduleval = computed(() => modelStorestate.$state.module);
const depend_libstore = computed(() => modelStorestate.$state.depend_lib);

const { proxy } = getCurrentInstance()
const show_upload = ref(false) // 显示上传布局
const showDisabled = ref(false)
const depend_lib = ref(false)
const router = useRouter()
const route = useRoute()
const md = new MarkdownIt({
    html: true,          // 启用HTML标签
    breaks: true,        // 将换行符转换为<br>
    linkify: true,       // 自动将URL转为链接
    typographer: true,   // 启用一些语言中立的替换和引号
    highlight: function (str, lang) {
        // 代码高亮处理
        if (lang && hljs.getLanguage(lang)) {
            try {
                return '<pre class="hljs"><code>' +
                    hljs.highlight(lang, str).value +
                    '</code>' + addCopyButton() + '</pre>';
            } catch (__) { }
        }
        return '<pre class="hljs"><code>' + md.utils.escapeHtml(str) + '</code>' + addCopyButton() + '</pre>';
    }
});

function addCopyButton() {
    return `<el-icon class='copy_btnson' size="20" onclick="copyCode(this)"><DocumentCopy />复制</el-icon>`;

}
window.copyCode = function (event) {
    const code = event.previousElementSibling;  // 获取代码块
    const text = code.textContent || code.innerText;  // 获取要复制的文本内容
    copyText(text)
};

// 用于API请求的文本处理函数
const prepareTextForApi = (text) => {
    if (!text) return '';

    // 先渲染为 Markdown
    let textplus = renderMarkdown(text);

    // 创建一个虚拟的 DOM 元素来处理渲染后的 HTML 内容
    const tempDiv = document.createElement('div');
    tempDiv.innerHTML = textplus;

    // 获取纯文本内容并替换掉 <br> 标签为换行符 \n
    let pureText = tempDiv.innerText || tempDiv.textContent;

    // 替换掉可能的 <br> 标签为换行符
    pureText = pureText.replace(/(\n)/g, '\n');  // 保证文本换行符被正确处理

    // 输出纯文本，保留换行符

    return pureText
};


// 改进的Markdown渲染函数，需要在使用前定义
const renderMarkdown = (content) => {
    if (!content) return '';



    // 处理特殊字符和转义
    let preprocessed = content
        .replace(/\\n/g, '\n')         // 处理换行
        .replace(/\\"/g, '"')          // 处理引号
        .replace(/\\t/g, '\t')         // 处理制表符
        .replace(/\\\\/g, '\\');       // 处理反斜杠

    // 处理可能被错误编码的Markdown符号
    preprocessed = preprocessed
        .replace(/&amp;/g, '&')
        .replace(/&lt;/g, '<')
        .replace(/&gt;/g, '>')
        .replace(/&#39;/g, "'")
        .replace(/&quot;/g, '"');

    // 确保代码块正确渲染
    preprocessed = preprocessed.replace(/```(\w+)?\n([\s\S]*?)```/g, (match, lang, code) => {
        return '```' + (lang || '') + '\n' + code + '```';
    });

    try {
        return md.render(preprocessed);
    } catch (error) {
        // console.error("Markdown渲染错误:", error);
        return `<p>内容格式错误: ${error.message}</p><pre>${content}</pre>`;
    }
};

const props = defineProps({
    // input输入词
    initialQuestion: {
        type: String,
        default: ''
    },
    // 当前知识库 obj
    currentKnowledge: {
        type: [Object, String],
        default: ''
    },
    // 对话记录（知识库、首页历史）
    dialogues: {
        type: Object,
        default: ''
    },
    // 最新一条对话记录
    enddata: {
        type: [Array, Object],
        default: ''
    },
    // 当前历史id （包含新的session_id）
    currentHistory: {
        type: [String, Number],
        default: ''
    },
    // files_appendix  知识库文件数组对象
    files_appendixobj: {
        type: [Array, Object, String],
        default: ''
    }
})

const emit = defineEmits(['succseechat', 'changestop', 'updateonUnmounted', 'CLEARSEARCH'])

// 搜索值
const search = ref(props.initialQuestion)
const search_back = ref(props.initialQuestion)
const messageBackupList = ref([]) // 备份对话列表
const chatLayout = ref(null)
const tip = ref('内容由 AI 引擎生成，仅供参考')

// 模型选项
let modelOptions = ref([])
let currentModel = ref(null)
// 知识库搜索选项
let klbOptions = ref([{
    label: '日常对话',
    value: 0,
    text: '日常对话聊天，不会受知识库干扰'
}, {
    label: '知识库搜索',
    value: 1,
    text: '将从现有的知识库中搜索相关信息'
}])
let currentklb = ref(null)
// 导入共享知识库弹窗
const Toleadintoopen = ref(false)
const tableData = ref([])
const ids = ref(new Set());
const isIndeterminate = ref([])
const istemporarily = ref([])
const mindmap = {
    editable: false,               // 【可选】是否允许编辑（默认 true）
    theme: 'primary',                   // 【可选】主题名称，比如 'primary'、'warning'，默认 null（自定义）
    mode: 'full',                  // 【可选】布局模式，默认 'full'
    // 可选值：
    // - 'full'：左右展开
    // - 'side'：只从右侧展开
    // - 'left'：只从左侧展开

    support_html: true,            // 【可选】节点内容是否支持 HTML，默认 false

    view: {                        // 【可选】视图配置（影响视觉和交互）
        engine: 'canvas',           // 渲染引擎，'canvas' 或 'svg'，默认 'canvas'
        hmargin: 10,                 // 思维导图左右边距，单位像素（默认 100）
        vmargin: 50,                // 思维导图上下边距，单位像素（默认 50）
        line_width: 1,              // 连线粗细，单位像素（默认 2）
        line_color: '#69b8fc',         // 连线颜色（默认 '#555'）
        line_style: 'curved',       // 连线样式，'straight'（直线）或 'curved'（曲线），默认 'curved'
        custom_line_render: null,   // 自定义连线绘制方法，默认 null（用内置绘制）
        draggable: false,           // 是否可以拖拽节点，默认 true
        hide_scrollbars_when_draggable: false, // 拖动时是否隐藏滚动条（默认 false）
        node_overflow: 'hidden',    // 节点内容溢出处理，默认 'visible'，可以设置 'hidden'
    },

    layout: {                      // 【可选】布局配置（影响节点排布）
        hspace: 30,                 // 同级节点水平间距，单位像素（默认 30）
        vspace: 20,                 // 同级节点垂直间距，单位像素（默认 20）
        pspace: 13,                 // 父子节点之间的垂直间距，单位像素（默认 13）
        cousin_space: 0             // 表兄弟节点间的额外距离，单位像素（默认 0）
    },

    autoLayout: true,               // 【可选】启用自动布局，当节点数量变化时自动重新排版（默认 false）

    shortcut: {                    // 【可选】快捷键配置（如果支持快捷键）
        enable: false,              // 是否启用快捷键（默认 true）
        handles: {},                // 自定义快捷键处理
        mapping: {}                 // 快捷键映射（比如回车添加子节点等）
    },

    default_event_handle: {         // 【可选】默认事件处理器
        enable_mousedown_handle: true,    // 是否启用鼠标按下事件
        enable_click_handle: true,        // 是否启用单击节点事件
        enable_dblclick_handle: true,     // 是否启用双击节点事件
        enable_mousewheel_handle: true    // 是否启用滚轮缩放事件
    },

    elastic: true,                // 【可选】是否启用弹性布局（比如节点超出范围时自动扩展画布）

    before_node_move: null,        // 【可选】节点拖动前的钩子函数
    before_node_remove: null,      // 【可选】节点删除前的钩子函数
    before_node_click: null,       // 【可选】节点点击前的钩子函数
}
const isSpeaking = ref(false)  // 确保 isSpeaking 在这里定义
const scaleFactor = ref(Math.max(0.1, Math.min(window.innerWidth / 1920, 1))) // 添加缩放因子

// 添加窗口大小变化监听器
const updateScale = () => {
    scaleFactor.value = Math.max(0.1, Math.min(window.innerWidth / 1920, 1))
    // 更新 CSS 变量
    document.documentElement.style.setProperty('--scale-factor', scaleFactor.value)
}

watch(() => props.dialogues, (newVal) => {
    if (newVal) {
        if (!renderMarkdown) {
            return
        }
        messageBackupList.value = []
        props.dialogues.forEach(message => {
            messageBackupList.value.push({
                role: 'user',
                content: renderMarkdown(message.problem),
                _id: message._id,
            })

            message.answer = normalizeQuoteBlocks(message.answer);

            messageBackupList.value.push({
                role: 'assistant',
                content: renderMarkdown(message.answer),
                foundresult: message.source,
                files_appendix: message.files_appendix,

                depend_lib: message.depend_lib,
                _id: message._id,
                disagree: message.disagree,
                agree: message.agree,
            })
        })

        nextTick(() => {
            scrollToBottom()
        })

    }
}, { immediate: true })
watch(() => props.enddata, (newVal) => {
    if (newVal) {
        messageBackupList.value[messageBackupList.value.length - 1]._id = newVal._id
    }
}, { immediate: true })
/* 知识库问答时的打断 */
watch(() => props.currentKnowledge, (newVal, oldVal) => {
    if (newVal && oldVal) {
        // 如果切换到不同的知识库，且当前正在回答中
        if (newVal._id !== oldVal._id) {

            if (showDisabled.value) {
                // 正在回答中，设置标记中断当前回答
                // console.log('正在回答中，中断当前回答')
                isstopation()
                stop_dialogue({
                    id: oldVal._id,
                    type: 2,
                })

            }
        }

    }
}, { immediate: true })
/* 历史记录问答时的打断 */
watch(() => props.currentHistory, (newVal, oldVal) => {
    if (newVal && oldVal) {
        // 如果切换到不同的知识库，且当前正在回答中
        if (newVal !== oldVal) {
            // clearexportparams()
            if (showDisabled.value) {
                // 正在回答中，设置标记中断当前回答
                // console.log('正在回答中，中断当前回答')
                isstopation()
                stop_dialogue({
                    id: oldVal,
                    type: 1,
                })
            }
        }

    }
}, { immediate: true })



// 检查内容是否为空白
const isEmptyContent = (str) => {
    return !str || str.trim().length === 0;
};

// 修改键盘事件处理
const handleKeydown = (event) => {
    // 当按下Enter键时
    if (event.key === 'Enter') {
        // 如果同时按下Ctrl键，手动插入换行符
        if (event.ctrlKey) {
            // 阻止默认行为
            event.preventDefault();

            // 获取当前光标位置
            const cursorPos = event.target.selectionStart;
            const textBefore = search.value.substring(0, cursorPos);
            const textAfter = search.value.substring(cursorPos);

            // 在光标位置插入换行符
            search.value = textBefore + '\n' + textAfter;

            // 设置新的光标位置
            nextTick(() => {
                event.target.selectionStart = cursorPos + 1;
                event.target.selectionEnd = cursorPos + 1;
            });
        } else {
            // 检查输入内容是否为空或仅包含空白字符
            if (!isEmptyContent(search.value)) {
                // 如果有实际内容，才发送消息并阻止默认行为
                event.preventDefault();
                sendHeadler();
            }
            // 否则允许换行行为发生
        }
    }
};

// 发送消息处理函数
const sendHeadler = () => {
    // 再次检查内容是否为空或仅包含空白字符
    if (isEmptyContent(search.value)) return;

    if (showDisabled.value === false) {
        loadingscroll.value = false
        // 存储去除首尾空格的内容
        search_back.value = search.value.trim();
        getSSE(search_back.value);
        showDisabled.value = true;
    }
};
// 总结内容
const summarycontent = () => {
    loadingscroll.value = false
    search.value = '总结内容'
    getSSE('总结内容')
    showDisabled.value = true;
};

let currentController = null;  // 用于存储当前的 AbortController




// 输入框监听事件
const searchChange = (e) => {
    if (search.value !== '') {
        clearTimeout(debounceTimer);
        debounceTimer = setTimeout(() => {
            getQuestionList();
            isShow.value = true
            document.documentElement.style.setProperty('--primary-val', '350px');
        }, 500);
    }
};
// 联想词汇
const getQuestionList = () => {
    getQuestion({ question: search.value }).then(res => {
        if (res.data == []) {
            questionList.value.push('未检测到相关问题，请重新提问。')
        } else {
            questionList.value = res.data
        }
    })
}
// 选择联想词汇
const sendTipQuestion = (item) => {
    search.value = item
    // handleSearch()
    // stopimportchange()
    getSSE(search.value)
}
const getSSE = async (search_que) => {
    stopimportchange()
    messageBackupList.value.push({
        role: 'user',
        content: search_que
    })
    messageBackupList.value.push({
        role: 'assistant', // assistant
        content: '',
        back: '',
        loading: true,
        netlisk: [],
    })

    getAnswer({ question: search.value }).then(result => {
        const BaserUrldev = 'http://192.168.110.196:9999'
        const BaserUrlprod = 'https://iot.hbqdcc.com'

        messageBackupList.value[messageBackupList.value.length - 1].loading = false

        if (result.code != 200) {
            messageBackupList.value[messageBackupList.value.length - 1].content = '服务器繁忙，请稍后再试。'
            return
        } else {
            if (result.data.message) {
                messageBackupList.value[messageBackupList.value.length - 1].content = result.data.message
            }
        }
        // 1、
        if (search.value.includes('系统运行状态？') && result.data.total) {
            let offline = result.data.offline
            let online = result.data.online
            let total = result.data.total
            messageBackupList.value[messageBackupList.value.length - 1].content = `平台共计 ${total} 台设备，其中 ${online} 台设备在线， ${offline} 台设备离线 ， ${online} 台设备正在运行`
            speakText(messageBackupList.value[messageBackupList.value.length - 1].content)
            messageBackupList.value[messageBackupList.value.length - 1].netlisk.push({
                title: '前往查看',
                url: `${BaserUrlprod}/projectCenter/equipmentHomepage`
            })
        }

        // 2、待完善
        if (search.value.includes('各项目是否运行正常？')) {

            if (result.data == null || result.data?.length == 0) {
                messageBackupList.value[messageBackupList.value.length - 1].content = `所有项目运行正常无报警信息`
                speakText(messageBackupList.value[messageBackupList.value.length - 1].content)
            } else {
                let resultText = '';
                let resultTextinp = '';
                result.data.forEach(project => {
                    const { projectName, alarmRecord } = project;
                    if (!alarmRecord || alarmRecord.length === 0) return;
                    alarmRecord.forEach(record => {
                        if (record.alarmLevel === "0") {
                            resultText += `${projectName}项目存在一条一级报警记录，报警内容为 ${record.alarmDetail}。<br>`;
                            resultTextinp += `${projectName}项目存在一条一级报警记录，报警内容为 ${record.alarmDetail}。`;
                        }
                        if (record.alarmLevel === "1") {
                            resultText += `${projectName}项目存在一条<span style="color: yellow; ">二级报警</span>记录，报警内容为 ${record.alarmDetail}。<br>`;
                            resultTextinp += `${projectName}项目存在一条二级报警记录，报警内容为 ${record.alarmDetail}。`;
                        }
                        if (record.alarmLevel === "2") {
                            resultText += `${projectName}项目存在一条<span style="color: red; ">三级报警</span>记录，报警内容为 ${record.alarmDetail}。<br>`;
                            resultTextinp += `${projectName}项目存在一条三级报警记录，报警内容为 ${record.alarmDetail}。`;
                        }
                    });
                });
                // 移除最后一个逗号
                if (resultText.endsWith('，')) {
                    resultText = resultText.slice(0, -1);
                }
                speakText(resultTextinp)
                messageBackupList.value[messageBackupList.value.length - 1].content = resultText
                messageBackupList.value[messageBackupList.value.length - 1].netlisk.push({
                    title: '前往查看',
                    url: `${BaserUrlprod}/alarmManager/alarmIndex?projectId=VqCt9MNCfQG`
                })
            }
        }
        // 3、
        const match = search.value.match(/调取(.+?)项目的报警记录/);
        if (match) {
            const projectName = match[1];
            const alarmRecords = result.data;

            if (result.data.data == null || result.data.data.length == 0) {
                console.log(result);

                messageBackupList.value[messageBackupList.value.length - 1].content = `暂无${projectName}项目的报警记录`
            } else {
                messageBackupList.value[messageBackupList.value.length - 1].content = renderMarkdown(generateMarkdownTable(alarmRecords.data))
                // 项目id
                let projectId = alarmRecords.projectId
                messageBackupList.value[messageBackupList.value.length - 1].netlisk.push({
                    title: '前往查看',
                    url: `${BaserUrlprod}/projectCenter/realtimealarm?projectId=${projectId}`
                })
            }
        }
        // 4、
        const matchhis = search.value.match(/调取(.+?)项目的历史报警记录/);
        if (matchhis) {
            const projectName = matchhis[1];
            const alarmRecords = result.data;
            if (result.data.data == null || result.data.data.length == 0) {
                messageBackupList.value[messageBackupList.value.length - 1].content = `暂无${projectName}项目的历史报警记录`
            } else {
                messageBackupList.value[messageBackupList.value.length - 1].content = renderMarkdown(generateMarkdownTable(alarmRecords.data))
                // 项目id
                let projectId = alarmRecords.projectId
                messageBackupList.value[messageBackupList.value.length - 1].netlisk.push({
                    title: '前往查看',
                    url: `${BaserUrlprod}/projectCenter/historyalarm?projectId=${projectId}`
                })
            }
        }
        // 5、
        const energytoday = search.value.match(/调取(.+?)项目的当日的运行能耗/);
        if (energytoday) {
            const projectName = energytoday[1];

        }
        // 6、
        const energyaweek = search.value.match(/调取(.+?)项目的一周的运行能耗/);
        if (energyaweek) {
            const projectName = energyaweek[1];
        }
        // 7、
        const energyonemonth = search.value.match(/调取(.+?)项目的一月的运行能耗/);
        if (energyonemonth) {
            const projectName = energyonemonth[1];
        }
        // 8、
        const energyrunstatus = search.value.match(/调取(.+?)项目的运行状态/);
        if (energyrunstatus) {
            const projectName = energyrunstatus[1];
            if (result.data == null || result.data.length == 0) {
                messageBackupList.value[messageBackupList.value.length - 1].content = `暂无${projectName}项目的运行状态`
            } else {
                let resultText = '';
                let resultTextinp = '';
                resultText += `<p>${projectName}项目正在运行：</p>`
                resultTextinp += `${projectName}项目正在运行：`
                result.data.map(item => {
                    resultText += `&emsp;&emsp;${item.variantName}为：${item.variantValue} ℃。<br>`
                    resultTextinp += `${item.variantName}为：${item.variantValue} ℃`
                })
                // 移除最后一个逗号
                if (resultText.endsWith('，')) {
                    resultText = resultText.slice(0, -1);
                }
                speakText(resultTextinp)
                messageBackupList.value[messageBackupList.value.length - 1].content = resultText
            }
        }
        // 9、
        const energytodayrtocurve = search.value.match(/调取(.+?)项目的当日蓄热室的运行曲线/);
        if (energytodayrtocurve) {
            const projectName = energytodayrtocurve[1];

            result.data.variableconfig.map(item => {
                // 项目id
                messageBackupList.value[messageBackupList.value.length - 1].netlisk.push({
                    title: item.variantName,
                    url: `${BaserUrldev}/projectCenter/realTimeData?projectId=${result.data.projectId}&device=${result.data.deviceId}:${item.id}&variantName=${item.variantName}`
                })
            })


        }
        // 10、
        const energytodayexitcurve = search.value.match(/调取(.+?)项目的当日出口的运行曲线/);

        if (energytodayexitcurve) {
            const projectName = energytodayexitcurve[1];
            result.data.variableconfig.map(item => {
                messageBackupList.value[messageBackupList.value.length - 1].netlisk.push({
                    title: item.variantName,
                    url: `${BaserUrldev}/projectCenter/realTimeData?projectId=${result.data.projectId}&device=${result.data.deviceId}:${item.id}&variantName=${item.variantName}`
                })
            })
        }
        // 11、
        // const energytodayfszlandcocurve = search.value.match(/调取(.+?)沸石转轮\+CO调取当日脱附温度的运行曲线/);
        const energytodayfszlandcocurve = search.value.match(/调取(.+?)项目的当日脱附温度的运行曲线/);

        if (energytodayfszlandcocurve) {
            const projectName = energytodayfszlandcocurve[1];
            result.data.variableconfig.map(item => {
                messageBackupList.value[messageBackupList.value.length - 1].netlisk.push({
                    title: item.variantName,
                    url: `${BaserUrldev}/projectCenter/realTimeData?projectId=${result.data.projectId}&device=${result.data.deviceId}:${item.id}&variantName=${item.variantName}`
                })
            })

        }
        // 12、
        if (search.value.includes('返回主控制界面')) {
            messageBackupList.value[messageBackupList.value.length - 1].netlisk.push({
                title: '前往查看主控制界面',
                url: `${BaserUrlprod}/projectCenter/equipmentHomepage`
            })
        }
        stopflow()
        // 通知父组件对话结束
        // emit('succseechat', true)
    }).catch(error => {
        stopflow()
        messageBackupList.value[messageBackupList.value.length - 1].loading = false
        messageBackupList.value[messageBackupList.value.length - 1].content = error
    })

}
function stopflow() {
    nextTick(() => {
        scrollToBottomchange()
    })
    showDisabled.value = false
    search_back.value = null
    search.value = null
}
function generateMarkdownTable(alarmRecords) {
    const header = [
        "项目名称", "报警详情", "报警级别",
        "报警时间", "确认类型", "采集器名称",
        "恢复确认类型", "恢复时间"
        // "恢复确认类型(0:未恢复,1:已恢复)", "恢复时间"
    ];

    const lines = [];
    lines.push("| " + header.join(" | ") + " |");
    lines.push("|" + header.map(() => "---").join("|") + "|");

    for (const record of alarmRecords) {
        const alarmTime = record.alarmTime;
        lines.push("| " +
            [
                record.projectName || "",
                record.alarmDetail || "",
                record.alarmLevel == 0 ? '一般' : record.alarmLevel == 1 ? '重要' : record.alarmLevel == 2 ? '紧急' : '' || "", // 报警分组无数据
                `${alarmTime.year} - ${String(alarmTime.monthValue).padStart(2, '0')
                } -${String(alarmTime.dayOfMonth).padStart(2, '0')} ` +
                `${String(alarmTime.hour).padStart(2, '0')}:${String(alarmTime.minute).padStart(2, '0')}:${String(alarmTime.second).padStart(2, '0')} `,
                record.confirmType == 0 ? '手动' : record.confirmType == 1 ? '自动' : record.confirmType == 2 ? '恢复手动' : '' || "", // 报警分组无数据
                record.deviceName || "",
                record.restore == 0 ? '未恢复' : record.restore == 1 ? '已恢复' : '' || "",
                record.restoreTime || "",

            ].join(" | ") +
            " |"
        );
    }

    return lines.join("\n");
}
let stopimport = ref();
// 暂停输入
const stopimportchange = () => {
    stopimport.value.stopimportfun()
}
// 处理语音识别结果
const handleSpeechResult = (result) => {
    if (result === '') {
        // 如果是空字符串，说明是开始新的录音，清空输入框
        search.value = ''
    } else {
        // 否则追加识别结果
        search.value += result
        getQuestionList()
    }
}
let isDigitalHumanVisible = ref(true) // 控制数字人是否可见
// 开启数字人
async function startxzs() {
    isDigitalHumanVisible.value = true
    // 等待动画完成后再显示
    await new Promise(resolve => setTimeout(resolve, 100))
}

// 收起数字人
async function hideDigitalHuman() {
    isDigitalHumanVisible.value = false
    // 等待动画完成后再隐藏，增加延迟时间让过渡更平滑
    await new Promise(resolve => setTimeout(resolve, 1000))
}

// 收起/展开
function hot_questionisshow() {
    if (questionList.value.length == 0) return
    isShow.value = !isShow.value
    if (isShow.value) {
        document.documentElement.style.setProperty('--primary-val', '350px');
    } else {
        document.documentElement.style.setProperty('--primary-val', '150px');
    }
}
function normalizeQuoteBlocks(text) {
    return text.replace(/'({[^{}]*"origin"\s*:\s*"[^"]+"[^{}]*})'/g, (match, jsonStr) => {
        try {
            const obj = JSON.parse(jsonStr);
            if (obj.origin) {
                return `< span class="quote" ><span class="textspan">${'*'}</span><span class="dropdown-content">${obj.origin}</span></span >`;
            }
        } catch (e) {
            // 忽略解析失败的项
        }
        return match; // 保留原样
    });
}

const loadingscroll = ref(false); // 控制是否加载中
// 滚动到最底部的函数
const scrollToBottom = () => {
    const scrollElement = document.querySelector('.content_layoutfa');

    if (!loadingscroll.value) {
        scrollElement.scrollTop = scrollElement.scrollHeight;  // 滚动到底部
    }
};
const scrollToBottomchange = () => {
    loadingscroll.value = false
    scrollToBottom()
};
const sentinel = ref(null);  // 哨兵元素的ref
const addIntersectionObserver = () => {
    const observer = new IntersectionObserver(
        (entries) => {
            entries.forEach((entry) => {
                // 当哨兵元素进入视口时触发加载更多数据的操作
                if (entry.isIntersecting) {
                    loadingscroll.value = false;  // 用户滚动到底部，加载更多数据
                } else {
                    loadingscroll.value = true;  // 用户滚动到底部，加载更多数据
                }
            });
        },
        {
            root: null, // 默认监听整个视口
            threshold: 0, // 当元素进入视口的任何部分时都触发
            rootMargin: '0px', // 可根据需要调整，确保能及时触发
        }
    );
    observer.observe(sentinel.value);
}
// 停止生成回答
const stopGeneration = () => {
    if (currentController) {
        currentController.abort();
        showDisabled.value = false
        const currentMessage = messageBackupList.value[messageBackupList.value.length - 1]
        currentMessage.loading = false
        currentMessage.foundloading = false
        currentMessage.content = currentMessage.content || '回答已终止'
        // 通知父组件对话结束
        emit('changestop', true)
        if (props.currentKnowledge) {
            stop_dialogue({
                id: props.currentKnowledge._id,
                type: 2,
            })
        } else {
            stop_dialogue({
                id: props.currentHistory,
                type: 1,
            })
        }

    }
}
// 未回答完毕时的停止回答
const isstopation = () => {
    if (currentController) {
        currentController.abort();
        showDisabled.value = false
    }
}


// 相关篇章展开收起
const toggleDocsExpand = (item) => {
    item.isunpack = !item.isunpack
}
// 相关篇章文档点击
const handleDocClick = (doc) => {
    window.open(doc.url, '_blank')
}
// 前往查看
const openLink = (url) => {
    if (!url) return
    window.open(url, '_blank') // '_blank' 表示新窗口打开
}
// 清空对话 知识库
const handleClearChat = async () => {
    const result = await clear_msg({
        library_id: props.currentKnowledge._id
    })
    if (result.code == 200) {
        ElMessage.success('删除成功');
        messageBackupList.value = []
    }
};

// 关闭上传文件
const closeHeadler = () => {
    show_upload.value = !show_upload.value
}


// 通用复制函数
function copyText(textToCopy) {
    // 检查浏览器是否支持 Clipboard API 且是安全上下文
    if (navigator.clipboard && window.isSecureContext) {
        // 使用 Clipboard API 进行复制
        return navigator.clipboard.writeText(textToCopy)
            .then(() => {
                // 成功时提示用户
                ElMessage.success('复制成功');
            })
            .catch(() => {
                // 复制失败时给出提示
                ElMessage.error('复制失败，无法访问剪贴板');
            });
    } else {
        // 回退到使用 document.execCommand 来进行复制
        let textArea = document.createElement("textarea");
        textArea.value = textToCopy;
        // 使 text area 不在视口内，同时设置不可见
        textArea.style.position = "absolute";
        textArea.style.opacity = 0;
        textArea.style.left = "-999999px";
        textArea.style.top = "-999999px";
        document.body.appendChild(textArea);

        textArea.focus();
        textArea.select();

        return new Promise((res, rej) => {
            // 执行复制命令
            const isCopied = document.execCommand('copy');
            textArea.remove();  // 删除临时文本框
            if (isCopied) {
                // 复制成功时给出提示
                ElMessage.success('复制成功');
                res();
            } else {
                // 复制失败时给出提示
                ElMessage.error('复制失败，无法执行命令');
                rej();
            }
        });
    }
}

let queryParamsinto = reactive({
    page: 1,
    limit: 10,
})

const speechSynthesis = ref(null)
const currentUtterance = ref(null)
let isReadingEnabled = ref(false) // 是否启用朗读功能
// 文本转语音方法
const speakText = (text) => {
    if (!speechSynthesis.value || !isReadingEnabled.value) return

    // 如果正在播放，先停止
    if (isSpeaking.value) {
        speechSynthesis.value.cancel()
    }

    const utterance = new SpeechSynthesisUtterance(text)

    // 设置语音参数
    utterance.lang = 'zh-CN'
    utterance.rate = 1.0
    utterance.pitch = 1.0
    utterance.volume = 1.0

    utterance.onend = () => {
        isSpeaking.value = false
        currentUtterance.value = null
    }

    utterance.onstart = () => {
        isSpeaking.value = true
        currentUtterance.value = utterance
    }

    speechSynthesis.value.speak(utterance)
}

// 切换朗读状态
const toggleReading = () => {
    isReadingEnabled.value = !isReadingEnabled.value
    if (!isReadingEnabled.value && isSpeaking.value) {
        stopSpeaking()
    }
}

// 停止语音
const stopSpeaking = () => {
    if (speechSynthesis.value && isSpeaking.value) {
        speechSynthesis.value.cancel()
        isSpeaking.value = false
        currentUtterance.value = null
    }
}

// 动画配置
const MOUTH_CONFIG = {
    position: { x: 102, y: 160, width: 55, height: 25 },
    animation: {
        speed: 0.4,
        maxOpen: 5,
        minOpen: -9,
    },
    imagePath: mouthImage, // 使用导入的图片资源
};

// 状态管理
const mouthState = {
    isAnimating: true,
    isLoaded: false,
    currentOpen: 0,
    direction: 2,
    animationFrame: null,
};

// 防抖函数
const debounce = (fn, delay) => {
    let timer = null;
    return (...args) => {
        if (timer) clearTimeout(timer);
        timer = setTimeout(() => fn(...args), delay);
    };
};

// 初始化嘴巴图片
const mouthImg = new Image();
mouthImg.onload = () => {
    mouthState.isLoaded = true;
    if (mouthState.isAnimating) {
        startAnimation();
    } else {
        drawMouthStatic();
    }
};
mouthImg.onerror = (error) => {
    console.error('Failed to load mouth image:', error);
};
mouthImg.src = MOUTH_CONFIG.imagePath;

function drawMouthAnimation() {
    if (!mouthState.isLoaded) return;

    const canvas = document.getElementById("mouthCanvas");
    if (!canvas) return;

    const ctx = canvas.getContext("2d");
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    // 使用 transform 优化性能
    ctx.save();
    ctx.translate(
        MOUTH_CONFIG.position.x + MOUTH_CONFIG.position.width / 2,
        MOUTH_CONFIG.position.y + MOUTH_CONFIG.position.height / 2
    );
    ctx.scale(1, 1 + mouthState.currentOpen / MOUTH_CONFIG.position.height);
    ctx.translate(
        -MOUTH_CONFIG.position.width / 2,
        -MOUTH_CONFIG.position.height / 2
    );

    ctx.drawImage(
        mouthImg,
        0,
        0,
        mouthImg.width,
        mouthImg.height,
        0,
        0,
        MOUTH_CONFIG.position.width,
        MOUTH_CONFIG.position.height
    );
    ctx.restore();
}

function drawMouthStatic() {
    if (!mouthState.isLoaded) return;

    const canvas = document.getElementById("mouthCanvas");
    if (!canvas) return;

    const ctx = canvas.getContext("2d");
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.drawImage(
        mouthImg,
        0,
        0,
        mouthImg.width,
        mouthImg.height,
        MOUTH_CONFIG.position.x,
        MOUTH_CONFIG.position.y,
        MOUTH_CONFIG.position.width,
        MOUTH_CONFIG.position.height
    );
}

function updateAnimation() {
    if (!mouthState.isAnimating) {
        mouthState.animationFrame = null;
        return;
    }

    mouthState.currentOpen += MOUTH_CONFIG.animation.speed * mouthState.direction;

    if (mouthState.currentOpen > MOUTH_CONFIG.animation.maxOpen) {
        mouthState.direction = -1;
    } else if (mouthState.currentOpen < MOUTH_CONFIG.animation.minOpen) {
        mouthState.direction = 1;
    }

    drawMouthAnimation();
    mouthState.animationFrame = requestAnimationFrame(updateAnimation);
}

function startAnimation() {
    if (!mouthState.animationFrame) {
        updateAnimation();
    }
}

function stopAnimation() {
    if (mouthState.animationFrame) {
        cancelAnimationFrame(mouthState.animationFrame);
        mouthState.animationFrame = null;
    }
    drawMouthStatic();
}

// 使用防抖处理动画状态切换
const setMouthAnimate = debounce((on) => {
    mouthState.isAnimating = on;
    if (on) {
        startAnimation();
    } else {
        stopAnimation();
    }
}, 100);

// 组件卸载时清理
onBeforeUnmount(() => {
    stopAnimation();
});

// 监听说话状态变化
watch(
    () => isSpeaking.value,
    (newVal) => {
        if (newVal) {
            // 开始说话时，启动嘴巴动画
            setMouthAnimate(true);
        } else {
            // 停止说话时，停止嘴巴动画
            setMouthAnimate(false);
        }
    },
    { immediate: true }, // 立即执行一次，确保初始状态正确
);

onMounted(() => {
    // 初始化语音合成
    speechSynthesis.value = window.speechSynthesis
    setMouthAnimate()
    // 初始化 CSS 变量
    document.documentElement.style.setProperty('--scale-factor', scaleFactor.value)
    window.addEventListener('resize', updateScale)

    // 原有的代码
    if (!props.currentHistory) {
        search_back.value = props.currentHistory
        sendHeadler()
    }

    search_back.value = props.initialQuestion
    // 新窗口发送对话
    if (search_back.value) {
        messageBackupList.value = []
        ids.value.add(...props.files_appendixobj.map(item => item._id))

        isIndeterminate.value = [...props.files_appendixobj]
        sendHeadler()
    }
    /* 哨兵模式 */
    addIntersectionObserver()

    document.documentElement.style.setProperty('--primary-val', '150px')
})
onUnmounted(() => {



    // 停止语音播放
    stopSpeaking()
    window.removeEventListener('resize', updateScale) // 移除窗口大小变化监听器

    if (currentController) {
        currentController.abort();
    }
    if (showDisabled.value) {
        if (props.currentKnowledge?._id) {
            /* 知识库 */
            isstopation()
            stop_dialogue({
                id: props.currentKnowledge?._id,
                type: 2,
            })
        } else {
            /* 历史 */
            isstopation()
            stop_dialogue({
                id: props.currentHistory,
                type: 1,
            })
            // 通知父组件 在未回答完时做出了切换
            emit('updateonUnmounted', true)
        }
    }
    // 通知父组件 在未回答完时做出了切换 对父组件输入值清空处理
    emit('CLEARSEARCH', true)





})


</script>

<style lang="scss" scoped>
.bg_img {
    width: 100%;
    height: 100vh;
    // background: url('../../assets/bg.png') no-repeat;
    background-size: cover;
}

.layout {
    width: 100%;
    height: 100vh;
    // padding: 24px;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    align-items: center;
    position: relative; // 作为定位父元素
}

.header_layout {
    width: 100%;
    // max-width: 1000px; // 与内容区域同宽
    height: 32px;
    display: flex;
    justify-content: flex-end; // 图标靠右
    align-items: center;
}

.content_wrapper {
    width: 100%;
    height: calc(100% - 240px); // 减去搜索框和padding的高度
    display: flex;
    justify-content: center;
    // padding: 0 0 0 25%;
}
.content_layoutfa {
    width: 100%;
    height: calc(100vh - var(--primary-val)); // 减去搜索框高度和padding
    overflow-y: auto;
    display: flex;
    justify-content: center;
}
.content_layout {
    width: 900px;
    // max-width: 1000px;
    // overflow-y: auto;
    // margin: 0 auto;
    background: transparent;
    // scroll-behavior: smooth;
    box-sizing: border-box;
    padding: 0 50px 0 0;
}
.bottom_arrow {
    width: 40px;
    height: 40px;
    background: #f2f2f2f2;
    position: absolute;
    top: calc(0% - 44px);
    left: 62%;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    cursor: pointer;
}
.content_layout::-webkit-scrollbar-track {
    background: transparent; // 轨道透明
    border-radius: 4px;
}

.content_layout::-webkit-scrollbar {
    width: 4px; // 减小滚动条宽度
    height: 4px;
}

.content_layout::-webkit-scrollbar-thumb {
    background: rgba(144, 147, 153, 0.3); // 淡灰色滑块
    border-radius: 4px;
    transition: background 0.2s; // 添加过渡效果

    &:hover {
        background: rgba(144, 147, 153, 0.5); // 悬停时加深
    }
}

// 隐藏水平滚动条
.content_layout::-webkit-scrollbar-track:horizontal {
    display: none;
}

.content_layout::-webkit-scrollbar-thumb:horizontal {
    display: none;
}

.chat_content {
    margin-top: 32px;
    font-size: 14px;
    width: 100%;
    display: flex;
    flex-direction: column;
}

.chat_layout {
    display: flex;
    align-items: flex-start;
    // max-width: 80%;  // 限制最大宽度
    // max-width: 80%;
}

.answer {
    width: fit-content;
    // width: 700px; // 调整最大宽度
    padding: 12px 16px 0;
    border-radius: 12px 12px 0 12px;
    // background: #0078f8;
    color: #fff;
    font-size: 14px;
    line-height: 1.7;

    // Markdown内容样式
    :deep(p) {
        // margin: 0.8em 0;
        line-height: 1.6;
    }

    :deep(h1),
    :deep(h2),
    :deep(h3),
    :deep(h4),
    :deep(h5),
    :deep(h6) {
        margin-top: 1.2em;
        margin-bottom: 0.5em;
        font-weight: 600;
        line-height: 1.25;
    }

    :deep(h1) {
        font-size: 2em;
    }
    :deep(h2) {
        font-size: 1.6em;
    }
    :deep(h3) {
        font-size: 1.2em;
    }
    :deep(h4) {
        font-size: 0.8em;
    }

    :deep(code) {
        background-color: #f4f4f4f8;
        color: #3b3131;
        padding: 0.2em 0.4em;
        border-radius: 3px;
        font-family: "Helvetica Neue", Helvetica, Arial, "PingFang SC",
            "Hiragino Sans GB", "Heiti SC", "Microsoft YaHei",
            "WenQuanYi Micro Hei", sans-serif;

        font-size: 0.85em;
    }

    :deep(pre) {
        background-color: rgba(0, 0, 0, 0.2);
        border-radius: 6px;
        padding: 1em;
        margin: 1em 0;
        overflow: auto;

        code {
            background: transparent;
            padding: 0;
            color: #eee;
            font-size: 0.9em;
            line-height: 1.5;
        }
    }

    :deep(ul),
    :deep(ol) {
        padding-left: 2em;
        margin: 0.8em 0;
    }

    :deep(li) {
        margin-bottom: 0.5em;
    }

    :deep(blockquote) {
        margin: 1em 0;
        padding-left: 1em;
        border-left: 3px solid rgba(255, 255, 255, 0.5);
        color: rgba(255, 255, 255, 0.9);
    }

    :deep(a) {
        color: #090909;
        text-decoration: underline;

        &:hover {
            color: #0078f8;
        }
    }

    /* 表格整体优化 */
    :deep(table) {
        width: 100%;
        margin: 1em 0;
        border-collapse: collapse;
        border-radius: 6px;
        overflow: hidden;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);

        /* 表头样式优化 */
        th {
            background-color: #f0f0f0;
            border: 1px solid #ddd;
            padding: 10px;
            text-align: left;
            font-weight: 600;
            color: #333;
            position: relative;
        }

        /* 表格主体单元格样式 */
        td {
            border: 1px solid #ddd;
            padding: 10px;
            text-align: left;
            color: #333;
            background-color: #fff;
        }

        /* 给表格添加条纹效果 */
        tr:nth-child(even) td {
            background-color: #f9f9f9;
        }

        /* 鼠标悬停在行上的效果 */
        tr:hover td {
            background-color: #f2f8ff;
        }

        /* 为第一列添加一点视觉重点 */
        tr td:first-child {
            font-weight: 500;
        }

        /* 确保表格中的代码片段样式正确 */
        code {
            background-color: rgba(0, 0, 0, 0.05);
            padding: 2px 4px;
            border-radius: 3px;
            font-family: "Helvetica Neue", Helvetica, Arial, "PingFang SC",
                "Hiragino Sans GB", "Heiti SC", "Microsoft YaHei",
                "WenQuanYi Micro Hei", sans-serif;

            font-size: 0.85em;
        }
    }

    :deep(hr) {
        margin: 1.5em 0;
        border: none;
        border-top: 1px solid rgba(255, 255, 255, 0.3);
    }

    :deep(img) {
        max-width: 100%;
        border-radius: 4px;
        margin: 1em 0;
    }
}

.quiz {
    padding: 12px 16px;
    border-radius: 12px 12px 0 12px; // 调整气泡形状
    background: #3d96f6;
    color: #fff;
    font-size: 14px;
    line-height: 1.5;
    word-break: break-word;
    max-width: 646px;
    overflow: auto;
}
/* 设置滚动条整体宽度 */
::-webkit-scrollbar {
    width: 10px; /* 垂直滚动条宽度 */
    height: 10px; /* 水平滚动条高度 */
}

/* 设置滚动条轨道样式 */
::-webkit-scrollbar-track {
    background-color: #f1f1f1; /* 轨道背景颜色 */
    border-radius: 10px; /* 轨道圆角 */
}

/* 设置滚动条滑块样式 */
::-webkit-scrollbar-thumb {
    background-color: #d0d0d0; /* 滑块颜色 */
    border-radius: 10px; /* 滑块圆角 */
    border: 2px solid #f1f1f1; /* 滑块与轨道之间的间隔 */
}

/* 设置滑块在悬停时的样式 */
::-webkit-scrollbar-thumb:hover {
    background-color: rgb(211, 211, 211) 0d0; /* 悬停时的滑块颜色 */
}
.text_align_r {
    position: relative;
    top: 6px;
}

.uploadFile {
    padding: 8px 16px;
    border-radius: 8px;
    margin-bottom: 8px;

    .file_img {
        width: 24px;
        height: 24px;
        margin: 2px 4px;
    }

    .file_font {
        font-size: 12px;
    }
}

.assets_img {
    width: 35px;
    height: 35px;
    border-radius: 50%; // 圆形头像
    object-fit: cover;
}
.loading_img {
    width: 25px;
    height: 25px;
}

.margin_l10 {
    margin-left: 10px;
}

.margin_r10 {
    margin-right: 10px;
}

.img_icon {
    width: 26px;
    height: 16px;
}
.img_icon:nth-child(3) {
    width: 20px;
}

.file_content {
    width: 1000px;
    height: 212px;
    border-radius: 16px;
    padding: 16px 16px 0 16px;
    bottom: 206px;

    .content_file {
        .file_txt {
            font-size: 16px;
            line-height: 28px;
        }

        .file_close {
            width: 10.67px;
            height: 10.67px;
        }
    }

    .upload_file {
        padding-top: 13px;

        .upload {
            width: 1068px;
            height: 136px;
        }

        .upload_text {
            font-size: 20px;
            line-height: 28px;
        }

        .remark {
            font-size: 12px;
            line-height: 28px;
        }
    }
}

:deep(.el-upload-dragger) {
    background-color: rgba(245, 248, 255, 1) !important;
}

.search_layout {
    width: calc(100% - 48px);
    max-width: 900px;
    // max-height: 300px;
    border-radius: 16px;
    border: 2px solid rgba(182, 170, 255, 0.9411764706);
    padding: 10px 10px 50px 10px;
    background: rgba(255, 255, 255, 0.8);
    position: absolute; // 改为绝对定位
    // bottom: 33px;
    bottom: 28px;
    // left: 50%;
    // transform: translateX(-50%);
    box-sizing: border-box;
    z-index: 10;

    .stop-tip {
        position: absolute;
        top: calc(0% - 32px);
        left: 45%;
        transform: translateX(-50%);
        display: flex;
        align-items: center;
        cursor: pointer;
    }

    .file {
        position: absolute;
        left: 17px;
        bottom: 17px;
        display: flex;
        justify-content: center;

        .file_img {
            width: 24px;
            height: 24px;
        }

        .file_txt {
            font-size: 14px;
            font-weight: 400;
            line-height: 24px;
            color: rgba(5, 96, 252, 1);
            margin-left: 4px;
        }
    }
    .cardselectboxs {
        position: absolute;
        left: 16px;
        bottom: 8px;
        display: flex;
        align-items: center;
    }
    .cardselect {
        // position: absolute;
        // left: 16px;
        // bottom: 8px;
        display: flex;
        margin: 0 5px 0 0;
        .cardselectbox {
            user-select: none;
            cursor: pointer;
            padding: 8px;
            background: #dec8f0;
            border-radius: 15px;
            color: #ffffff;
        }
    }

    .search {
        position: absolute;
        right: 16px;
        bottom: 8px;
        cursor: pointer;
        display: flex;
        align-items: center;
        gap: 12px;

        .model-selector {
            display: flex;
            align-items: center;
            gap: 4px;
            padding: 6px 12px;
            border-radius: 6px;
            font-size: 14px;
            color: #333;
            background: #f5f7fa;
            transition: all 0.3s;

            &:hover {
                background: #e9ecf2;
            }

            .el-icon {
                font-size: 12px;
                color: #909399;
                transition: transform 0.3s;
            }
        }

        .search_img {
            width: 32px;
            height: 32px;
        }
    }
}

.input_layout {
    font-size: 16px;
}

::v-deep .el-textarea__inner {
    box-shadow: none !important;
    background: none !important;
    padding: 0 !important;
    resize: none !important; // 只禁用手动调整大小

    // 自定义滚动条样式
    &::-webkit-scrollbar {
        width: 4px;
        height: 4px;
    }

    &::-webkit-scrollbar-thumb {
        background-color: rgba(144, 147, 153, 0.3);
        border-radius: 4px;

        &:hover {
            background-color: rgba(144, 147, 153, 0.5);
        }
    }

    &::-webkit-scrollbar-track {
        background: transparent;
    }

    // Firefox 滚动条样式
    scrollbar-width: thin;
    scrollbar-color: rgba(144, 147, 153, 0.3) transparent;
}

// 左侧布局
.left_layout {
    display: flex;
    align-items: flex-start;
    margin-bottom: 24px;
}

// 右侧布局
.right_layout {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 24px;
}

.action-buttons {
    display: flex;
    align-items: center;
    gap: 8px; // 按钮之间的间距
    margin-top: 12px;
    padding: 4px;
    border-radius: 8px;
    background: rgba(247, 248, 250, 0.8); // 半透明背景
    backdrop-filter: blur(8px); // 毛玻璃效果
}

.action-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 6px;
    cursor: pointer;
    transition: all 0.2s ease;

    &:not(:last-child) {
        border-right: 1px solid rgba(232, 232, 232, 0.8);
        padding-right: 8px;
    }

    &:hover {
        background: rgba(103, 81, 240, 0.1); // 悬停效果
    }

    &:active {
        transform: scale(0.95); // 点击效果
    }
}

.action-icon {
    width: 16px;
    height: 16px;
    opacity: 0.6;
    transition: opacity 0.2s ease;

    &:hover {
        opacity: 1;
    }
}

.stop-btn {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 8px 16px;
    font-size: 14px;
    border-radius: 20px;
    background: #ff4d4f;
    border-color: #ff4d4f;
    transition: all 0.2s ease;
    color: #ffff;
    &:hover {
        background: #ff7875;
        border-color: #ff7875;
    }

    :deep(.el-icon) {
        font-size: 16px;
    }
}

// 添加空状态样式
.empty-chat-state {
    display: flex;
    justify-content: center;
    align-items: center;
    height: calc(100% - 10px); // 减去输入框的高度

    .empty-chat-content {
        display: flex;
        flex-direction: column;
        align-items: center;
        text-align: center;
        max-width: 320px;
        user-select: none;

        .chat-icon {
            width: 64px;
            height: 64px;
            margin-bottom: 24px;
            opacity: 0.8;
        }

        .empty-chat-title {
            font-size: 20px;
            font-weight: 600;
            color: #333;
            margin-bottom: 12px;
        }

        .empty-chat-text {
            font-size: 15px;
            color: #666;
            line-height: 1.6;
            background: linear-gradient(90deg, #4b6cb7 0%, #182848 100%);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            padding: 8px 16px;
            border-radius: 20px;
            background-color: rgba(75, 108, 183, 0.1);
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
            animation: pulse 2s infinite;
        }
    }
}

@keyframes pulse {
    0% {
        transform: scale(1);
    }
    50% {
        transform: scale(1.05);
    }
    100% {
        transform: scale(1);
    }
}

.no-result {
    margin-bottom: 16px;

    .no-result-tip {
        color: #909399;
        font-size: 14px;
        margin: 0;
    }
}

.related-docs {
    width: 350px;
    background: #e4f1ff;
    border-radius: 8px;
    // margin-bottom: 16px;
    user-select: none;
    .related-docs-header {
        padding: 12px 16px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        cursor: pointer;
        color: #409eff;
        font-size: 14px;

        .el-icon {
            transition: transform 0.3s;

            &.is-expand {
                transform: rotate(180deg);
            }
        }

        // &:hover {
        //     background: rgba(64, 158, 255, 0.1);
        // }
    }

    .related-docs-list {
        padding: 8px 16px;
        border-top: 1px solid rgba(64, 158, 255, 0.1);

        .doc-item {
            display: flex;
            align-items: center;
            padding: 8px 0;
            cursor: pointer;
            transition: all 0.3s;

            &:hover {
                color: #409eff;
            }

            .doc-index {
                width: 24px;
                color: #909399;
            }

            .doc-name {
                flex: 1;
                margin: 0 12px;
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
                color: #000000;
            }

            .doc-type {
                color: #909399;
                font-size: 12px;
            }
        }
    }
}

.ai-answer {
    overflow: auto !important;
    max-height: none !important;
    height: auto !important;
    color: #333;
    margin-top: 6px;
    font-size: 16px;
}

.operation-tip {
    margin-top: 12px;
    font-size: 12px;
    color: #909399;
    box-sizing: border-box;
    user-select: none;
    transition: bottom 0.2s ease; // 添加平滑过渡效果
    position: absolute;
    bottom: 8px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 10;
}

:deep(.el-dropdown-menu__item) {
    &.is-active {
        color: #409eff;
        font-weight: bold;
        background-color: #ecf5ff;
    }

    &:hover {
        background-color: #f5f7fa;
    }
}

.operation-buttons {
    margin-top: 12px;

    .button-group {
        display: flex;
        gap: 16px;
    }

    .operation-button {
        display: flex;
        align-items: center;
        gap: 4px;
        padding: 4px 8px;
        border-radius: 4px;
        cursor: pointer;
        transition: all 0.2s;
        color: #666;

        &:hover {
            background: rgba(0, 0, 0, 0.05);
            color: #333;
        }

        .button-icon {
            width: 16px;
            height: 16px;
        }

        .button-text {
            font-size: 13px;
        }
    }
}

.chat-panel-header {
    width: 100%;
    // height: 56px;
    padding: 0 16px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    // border-bottom: 1px solid #eee;

    .chat-title {
        font-size: 16px;
        font-weight: 500;
        color: #333;
    }

    .clear-chat-btn {
        color: blue;
        transition: all 0.2s;

        &:hover {
            color: #f56c6c;
            transform: scale(1.1);
        }

        .el-icon {
            font-size: 18px;
        }
    }
}
::v-deep .hljs {
    background-color: #f6f6f6 !important;
    border: 1px solid #ccc !important;

    /* 调整代码中所有文本的基本颜色，确保在浅色背景上可见 */
    color: #333 !important;
    // font-style: italic;
    position: relative;
    /* 覆盖常见的高亮文本颜色 */
    .hljs-tag,
    .hljs-keyword,
    .hljs-selector-tag,
    .hljs-literal,
    .hljs-strong,
    .hljs-name {
        color: #3a72ff !important; /* 深蓝色 */
    }

    .hljs-code,
    .hljs-attribute,
    .hljs-symbol,
    .hljs-regexp,
    .hljs-link {
        color: #d21111 !important; /* 深红色 */
    }

    .hljs-string,
    .hljs-bullet,
    .hljs-subst,
    .hljs-title,
    .hljs-section,
    .hljs-emphasis,
    .hljs-type,
    .hljs-built_in,
    .hljs-builtin-name,
    .hljs-selector-attr,
    .hljs-selector-pseudo,
    .hljs-addition,
    .hljs-variable,
    .hljs-template-tag,
    .hljs-template-variable {
        color: #37b50d !important; /* 深绿色 */
    }

    .hljs-comment,
    .hljs-quote,
    .hljs-deletion,
    .hljs-meta {
        color: #717171 !important; /* 深灰色 */
    }

    .hljs-doctag,
    .hljs-selector-id,
    .hljs-selector-class,
    .hljs-number {
        color: #871094 !important; /* 紫色 */
    }

    /* 针对所有的代码高亮块的最后润色 */
    border-radius: 6px;
    padding: 16px;
    line-height: 1.5;
    margin: 15px 0;
}

/* 确保代码中的 <code> 元素也使用适当的颜色 */
.answer :deep(pre) code {
    color: #333 !important;
    font-family: "Helvetica Neue", Helvetica, Arial, "PingFang SC",
        "Hiragino Sans GB", "Heiti SC", "Microsoft YaHei", "WenQuanYi Micro Hei",
        sans-serif;
}
::v-deep .copy_btnson {
    position: absolute;
    top: 3px;
    right: 15px;
    cursor: pointer;
    font-style: normal;
}
::v-deep .quote {
    display: inline-flex;
    background: #e4f1ff;
    padding: 0px 7px;
    text-align: center;
    justify-content: center;
    align-items: center;
    border-radius: 4px;
    font-size: 16px;
    border-radius: 50%;
    cursor: pointer;
    position: relative;
    height: 20px;

    .textspan {
        margin: 5px 0 0 0;
    }
}

::v-deep .quote .dropdown-content {
    display: none;
    position: absolute;
    background-color: #f9f9f9;
    //    min-width: 120px;
    padding: 8px;
    z-index: 999;
    border: 1px solid #ccc;
    border-radius: 8px;
    top: 100%;
    left: -100%;
    white-space: nowrap;
    box-shadow: 0 6px 21px 0 #1e1f2433;
}

::v-deep .quote:hover .dropdown-content {
    display: block;
}
.file-list-container {
    display: flex;
    flex-flow: wrap;
    padding: 0 0 0 5px;
    .card_bth {
        display: flex;
        align-items: center;
        margin: 0 0 0 5px;
        .div {
            padding: 6px;
            border-radius: 20px;
            background: #e9e8e8e2;
            cursor: pointer;
            margin: 0 5px 0 0;
            &:hover {
                box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); /* 悬浮时加重阴影 */
            }
        }
    }
}

.file-item {
    background-color: #fff;
    border-radius: 8px; /* 圆角 */
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); /* 轻微阴影 */
    padding: 10px;
    width: 230px;
    display: flex;
    flex-direction: row;
    align-items: center; /* 内容居中 */
    text-align: center;
    transition: transform 0.3s ease, box-shadow 0.3s ease;
    margin: 0 5px 5px 0;
    position: relative;
}

.file-item:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); /* 悬浮时加重阴影 */
}

.file-icon {
    width: 30px;
    height: 30px;
}

.file-info {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px; /* 文件名和元数据之间的间距 */
    margin: 0 20px 0 10px;
}

.file-name {
    font-size: 13px;
    font-weight: 600;
    color: #333;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 1;
    word-break: break-all;
    -webkit-box-orient: vertical;
}

.file-meta {
    font-size: 12px;
    color: #777;
    display: flex;
    /* flex-direction: row; */
    gap: 4px;
    /* text-align: left; */
    justify-content: left;
    width: 100%;
}

.file-meta div {
    margin: 0;
}
.delete-icon {
    position: absolute;
    top: 8px;
    right: 8px;
    background: transparent;
    border: none;
    font-size: 20px;
    color: #ff4d4f;
    cursor: pointer;
    transition: color 0.2s;
}

.delete-icon:hover {
    color: #ff0000; /* 悬浮时更改颜色 */
}
::v-deep .hide-header-checkbox .el-checkbox {
    display: none !important;
}

::v-deep jmexpander {
    line-height: 8px;
}
/* 美化下载按钮 */
.download-btn {
    padding: 5px;
    background: linear-gradient(145deg, #6e7f8f, #3b4756);
    color: white;
    border: none;
    border-radius: 10px;
    font-size: 14px;
    font-weight: bold;
    cursor: pointer;
    transition: all 0.3s ease;
    z-index: 99;
    width: 50px;
    position: absolute;
    top: 10px;
    right: 15px;
    text-align: center;
}

/* 按钮悬停效果 */
.download-btn:hover {
    background: linear-gradient(145deg, #3b4756, #6e7f8f); /* 改变渐变背景 */
    transform: scale(1.1); /* 放大按钮 */
}

/* 按钮按下效果 */
.download-btn:active {
    transform: scale(1); /* 恢复正常大小 */
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); /* 增加按下时的阴影效果 */
}

.Occupyposition {
    // height: 658px !important;
}

// 热门问题列表
.hot-question-list {
    height: 215px;
    overflow: auto;
    margin: 0 0 16px 0;
    display: grid;
    gap: 12px;

    .hot-question-item {
        display: flex;
        align-items: center;
        text-align: left;
        padding: 10px 16px;
        background: #f8fafc;
        border-radius: 12px;
        transition: all 0.2s ease;
        border: 1px solid transparent;
        cursor: pointer;

        .question-index {
            display: flex;
            align-items: center;
            margin-right: 12px;
            color: #64748b;

            .el-icon {
                margin-right: 6px;
                font-size: 16px;
                color: #4f46e5;
            }

            span {
                font-size: 14px;
                font-weight: 500;
            }
        }

        .hot-question-item-title {
            flex: 1;
            font-size: 14px;
            color: #1e293b;
            line-height: 1.5;
            letter-spacing: 0.01em;
        }

        .el-icon {
            color: #94a3b8;
            margin-left: 12px;
            transition: all 0.2s ease;
        }

        &:hover {
            background: #eef2ff;
            border-color: #e0e7ff;
            // transform: translateX(4px);

            .hot-question-item-title {
                color: #4f46e5;
            }

            .el-icon {
                color: #4f46e5;
                // transform: translateX(4px);
            }
        }
    }
}
.CollapseExpand {
    background: #409eff;
    color: #ffffff;
    padding: 5px;
    border-radius: 10px;
    border: transparent;
    cursor: pointer;
    // margin: 0 0 8px 0;
}
.xzs {
    width: 30px;
    height: 30px;
    margin: 0 10px 0 0;
    cursor: pointer;
}
.Digitalhuman {
    position: absolute;
    top: calc(-520px * var(--scale-factor));
    left: calc(-350px * var(--scale-factor));
    transition: all 0.8s cubic-bezier(0.4, 0, 0.2, 1);
    transform: scale(0.5);
    transform-origin: top center;
    opacity: 1;
    visibility: visible;

    &.hidden {
        transform: scale(0.1) translate(-100px, -100px);
        opacity: 0;
        visibility: hidden;
        transition: all 0.8s cubic-bezier(0.4, 0, 0.2, 1);
    }

    &.visible {
        transform: scale(1) translate(0, 0);
        opacity: 1;
        visibility: visible;
        transition: all 0.8s cubic-bezier(0.4, 0, 0.2, 1);
    }

    user-select: none;

    img {
        width: 300px;
        transition: opacity 0.5s ease-in-out;
    }

    .Readingswitch {
        display: flex;
        align-items: center;
        gap: 8px;
        padding: 8px 12px;
        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
        width: 90px;
        margin: 0px 0 0 30%;
        transition: opacity 0.3s ease-in-out;

        .reading-text {
            font-size: 14px;
            color: #606266;
            font-weight: 500;
        }

        :deep(.el-switch) {
            --el-switch-on-color: #13ce66;
            --el-switch-off-color: #ff4949;

            .el-switch__core {
                .el-switch__action {
                    .el-icon {
                        font-size: 12px;
                        color: #fff;
                    }
                }
            }
        }

        .btnimg {
            width: 20px;
            height: 20px;
            cursor: pointer;
            transition: transform 0.2s ease;
            margin: 0 10px 0 0;

            &:hover {
                transform: scale(1.1);
            }
        }
    }
}

.digital-human {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    transition: opacity 0.3s ease-in-out;
}

.digital-human img {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    transition: opacity 0.3s ease-in-out;
}

.markdown-container {
    height: 300px;
    overflow: auto;
}
</style>